﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using THO7AlgorithmBase;

namespace OCR_LEARN
{
    class GuidoOCR
    {
        private Bitmap TwoColor(Bitmap sourceImage)
        {
            Bitmap returnImage = new Bitmap(sourceImage);
            Rectangle rect = new Rectangle(0, 0, returnImage.Width, returnImage.Height);
            BitmapData myBmpData = returnImage.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr = myBmpData.Scan0;
            int numBytes = returnImage.Width * returnImage.Height * 3;
            byte[] rgbValues = new byte[numBytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, numBytes);
            for (int i = 0; i < rgbValues.Length; i += 3)
            {
                if (rgbValues[i] < 50 || rgbValues[i+1] < 50 || rgbValues[i+2] < 50)
                {
                    rgbValues[i] = 0;
                    rgbValues[i + 1] = 0;
                    rgbValues[i + 2] = 0;
                }
                else
                {
                    rgbValues[i] = 255;
                    rgbValues[i + 1] = 255;
                    rgbValues[i + 2] = 255;
                }
            }
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, numBytes);
            returnImage.UnlockBits(myBmpData);
            return returnImage;
        }
        //afbeelding kleiner maken totdat hij echt tegen de letter aan zit
        //middelste van de lijnen nemen zodat er een dunne lijn over blijft
        //vervolgens deze methodes erover heen doen
        //opdelen in veel meer vlakken en dan niet kijken hoeveel pixels er goed staan per vlak maar hoeveel vlakken goed zijn.
        //kijken hoeveel vlakken overeen komen.
        private const int verdeling = 5;


        public void learn(Bitmap sourceImage, String character)
        {
            //ik ga ervan uit dat de letters die vergeleken moeten worden net zo staan als de leer afbeeldingen
            //dus als de leerafbeeldingen scheef staan dan kan hij alleen scheefe letters herkennen
            //bestand uitlezen en naar een buffer schrijven.
            if (!File.Exists("GuidoOCR.txt"))
            {
                StreamWriter sw = new StreamWriter("GuidoOCR.txt", true);
                sw.Close();
            }
            StreamReader reader = new StreamReader("GuidoOCR.txt");
            List<String> characters = new List<String>();
            //lees het bestand uit
            String s = "";
            while ((s = reader.ReadLine()) != null)
            {
                characters.Add(s);
            }
            reader.Close();

            //plaatje bekijken
            Bitmap returnImage = new Bitmap(sourceImage);
            VisionAlgorithm fp = new remove_borders("");
            returnImage = TwoColor(returnImage);
            returnImage = fp.DoAlgorithm(returnImage);


            Rectangle rect = new Rectangle(0, 0, returnImage.Width, returnImage.Height);
            BitmapData myBmpData = returnImage.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr = myBmpData.Scan0;
            int numBytes = returnImage.Width * returnImage.Height * 3;
            byte[] rgbValues = new byte[numBytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, numBytes);

            int xGroote = returnImage.Width / verdeling + 1;
            //is niet goed want het delen door dat wordt afgerond dus ik heb +1 gedaan zodat hij niet vastloopt als hij hoger blijkt
            int yGroote = returnImage.Height / verdeling + 1;
            //deel het plaatje op in meerdere stukken
            int[] zwart = new int[verdeling * verdeling];
            int pixels = xGroote * yGroote;
            for (int i = 0; i < (rgbValues.Length/3); i++)
            {
                int xpositie = (i % returnImage.Width) / xGroote;
                int ypositie = ((i - (i % returnImage.Width)) / returnImage.Width) / yGroote;
                if (rgbValues[i*3] < 100)
                {
                    zwart[(ypositie * verdeling) + xpositie]++;
                }
            }
            //kijk per stuk hoeveel procent zwart is.
            int[] procenten = new int[verdeling * verdeling];
            for (int i = 0; i < (verdeling * verdeling); i++)
            {
                procenten[i] = ((zwart[i]*1000) / pixels);
            }

            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, numBytes);
            returnImage.UnlockBits(myBmpData);

            //kijk of er al een is die dezelfde letter heeft.
            Boolean gevonden = false;
            for (int i = 0; i < characters.Count; i++)
            {
                if (characters[i][0] == character[0])
                {
                    //combineer de waardes
                    //haal eerst de waardes uit de string van het tekst document
                    int[] f = new int[verdeling * verdeling + 1];
                    string[] words = characters[i].Split(' ');
                    for (int j = 1; j < (verdeling * verdeling) + 2; j++)
                    {
                        f[j-1] = int.Parse(words[j]);
                    }
                    String temp = character;
                    for (int j = 0; j < (verdeling * verdeling); j++)
                    {
                        f[j] = ((f[j] * f[verdeling * verdeling]) + procenten[j]) / (f[verdeling * verdeling] + 1);
                        temp += " " + f[j];
                    }
                    f[verdeling * verdeling]++;
                    temp += " " + f[verdeling * verdeling];
                    characters[i] = temp;
                    gevonden = true;
                    break;
                }
            }
            if (!gevonden)
            {
                String waardes = character;
                for (int j = 0; j < (verdeling * verdeling); j++)
                {
                    waardes += " " + procenten[j];
                }
                waardes += " " + 1;
                characters.Add(waardes);
            }
            //schrijf nu alle waardes terug naar de tekst file
            StreamWriter writer = new StreamWriter("GuidoOCR.txt");
            characters.Sort();
            for (int i = 0; i < characters.Count; i++)
            {
                writer.WriteLine(characters[i]);
            }
            writer.Close();
        }
    }
}
